package com.ly.heart.service.king;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.google.gson.Gson;
import com.kingdee.bos.webapi.entity.IdentifyInfo;
import com.kingdee.bos.webapi.entity.RepoRet;
import com.kingdee.bos.webapi.sdk.K3CloudApi;
import com.ly.common.exception.CustomException;
import com.ly.common.utils.DateUtils;
import com.ly.common.utils.SecurityUtils;
import com.ly.common.utils.erp.KingConstUtil;
import com.ly.heart.domain.*;
import com.ly.heart.domain.king.BaseChildBo;
import com.ly.heart.domain.king.badHandle.BadHandleBo;
import com.ly.heart.domain.king.badHandle.BadHandleFEntityBo;
import com.ly.heart.domain.king.order.FBillTypeIDBo;
import com.ly.heart.domain.king.order.OrderAuditBo;
import com.ly.heart.domain.king.order.OrderSubmitBo;
import com.ly.heart.domain.request.KingBaseSingleRequest;
import com.ly.heart.domain.response.KingBaseResponse;
import com.ly.heart.domain.response.KingBaseResponseSuccessEntity;
import com.ly.heart.service.IKingBadHandleService;
import com.ly.heart.service.IKingOrgService;
import com.ly.heart.util.CurrentUserUtil;
import com.ly.heart.util.KingCommonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;


/**
 * 不良品处理单推送Service
 */
@Component
@Slf4j
public class KingBadHandlePushService {

    private final SimpleDateFormat dateFormat = new SimpleDateFormat ( "yyyy-MM-dd" );

    @Resource
    private IKingBadHandleService badHandleService;
    @Resource
    private IKingOrgService iKingOrgService;

    /**
     * 公用金蝶推送方法
     * 合并保存，提交，审核三步
     * @param badHandleId
     */
    @Transactional( rollbackFor = Exception.class )
    public void push(String badHandleId){
        KingOrgEntity orgEntity = iKingOrgService.getOne ( new LambdaQueryWrapper<KingOrgEntity>().eq ( KingOrgEntity :: getOrgId, CurrentUserUtil.getCompanyId () ).eq ( KingOrgEntity::getIsDisabled, false ) );
        if ( orgEntity == null ) {
            throw new CustomException ( "请先至系统管理中配置金蝶账套！" );
        }
        IdentifyInfo identifyInfo = KingCommonUtil.getIdentifyInfo ( orgEntity );
        KingBadHandleEntity kingBadHandle = badHandleService.selectKingBadHandleEntityById(badHandleId);
        if(Objects.isNull(kingBadHandle)){
            throw new CustomException("不良品处理单不存在！");
        }
        if(kingBadHandle.getIsSend() == KingConstUtil.KING_DATA_IS_SEND_YES){
            throw new CustomException("该单据已推送金蝶,无需重复推送！");
        }
        try {
            K3CloudApi client = new K3CloudApi (identifyInfo);
            save(kingBadHandle,client);
            submit(kingBadHandle.getDocCode(),client);
            audit(kingBadHandle.getDocCode(),client);
            updateSendSuccess(badHandleId);
        }catch (Exception e){
            e.printStackTrace();
            throw new CustomException("推送不良品处理单失败！");
        }
    }

    /**
     * 修改推送状态
     * @param badHandleId
     * @return
     */
    private void updateSendSuccess(String badHandleId){
        KingBadHandleEntity kingBadHandle = new KingBadHandleEntity();
        kingBadHandle.setId(badHandleId);
        kingBadHandle.setIsSend(KingConstUtil.KING_DATA_IS_SEND_YES);
        kingBadHandle.setUpdateTime(DateUtils.getNowDate());
        kingBadHandle.setUpdateName(SecurityUtils.getLoginUser().getUser().getUserId());
        boolean flag = badHandleService.updateById(kingBadHandle);
        if(!flag){
            throw new CustomException("修改推送状态失败！");
        }
    }


    /**
     * 金蝶-不良品处理单保存
     * @param badHandle
     * @param client
     */
    public void save(KingBadHandleEntity badHandle, K3CloudApi client){
        try{
            String formId = KingConstUtil.QM_DEFECTPROCESSBILL;
            KingBaseSingleRequest singleRequest = new KingBaseSingleRequest ();
            BadHandleBo badHandleBo = this.assembleKingBadHandle(badHandle);
            singleRequest.setModel(badHandleBo);
            //调用接口
            String resultJson = client.save(formId, JSONObject.toJSONString(singleRequest));
            //用于记录结果
            Gson gson = new Gson();
            //对返回结果进行解析和校验
            RepoRet repoRet = gson.fromJson(resultJson, RepoRet.class);
            KingBaseResponse baseResponse = JSONObject.parseObject ( gson.toJson ( repoRet.getResult ().getResponseStatus () ), KingBaseResponse.class );
            if (baseResponse.getIsSuccess()) {
                log.info("不良品处理单推送成功: {}", gson.toJson(repoRet.getResult()));
                List<KingBaseResponseSuccessEntity> successEntities = baseResponse.getSuccessEntitys ();
                if(!CollectionUtils.isEmpty(successEntities)){
                    String docCode = successEntities.get(0).getNumber();
                    //修改为已推送状态
                    badHandleService.update(new LambdaUpdateWrapper<KingBadHandleEntity>().set(KingBadHandleEntity::getIsSend,KingConstUtil.KING_DATA_IS_SEND_YES).eq(KingBadHandleEntity::getDocCode,docCode));
                }
            } else {
                log.error("不良品处理单推送失败: " + gson.toJson(repoRet.getResult().getResponseStatus()));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 金蝶-不良品处理单提交
     * @param docCode
     * @param client
     */
    public void submit(String docCode, K3CloudApi client){
        try{
            OrderSubmitBo submitBo = new OrderSubmitBo();
            List<String> numbers = new ArrayList<>();
            numbers.add(docCode);
            submitBo.setNumbers(numbers);
            String formId = KingConstUtil.QM_DEFECTPROCESSBILL;
            String resultJson = client.submit(formId, JSON.toJSONString ( submitBo ));
            Gson gson = new Gson();
            RepoRet repoRet = gson.fromJson(resultJson, RepoRet.class);
            KingBaseResponse baseResponse = JSONObject.parseObject ( gson.toJson ( repoRet.getResult ().getResponseStatus () ), KingBaseResponse.class );
            if (baseResponse.getIsSuccess()) {
                log.info("不良品处理单提交成功: {}", gson.toJson(repoRet.getResult()));
            } else {
                log.error("不良品处理单提交失败: {}",gson.toJson(repoRet.getResult().getResponseStatus()));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 不良品处理单审核方法
     * @param docCode
     * @param client
     */
    public void audit(String docCode,K3CloudApi client){
        try{
            OrderAuditBo auditBo = new OrderAuditBo();
            List<String> numbers = new ArrayList<>();
            numbers.add(docCode);
            auditBo.setNumbers(numbers);
            String formId = KingConstUtil.QM_DEFECTPROCESSBILL;
            String resultJson = client.audit(formId,JSON.toJSONString ( auditBo ));
            Gson gson = new Gson();
            RepoRet repoRet = gson.fromJson(resultJson, RepoRet.class);
            KingBaseResponse baseResponse = JSONObject.parseObject ( gson.toJson ( repoRet.getResult ().getResponseStatus () ), KingBaseResponse.class );
            if (baseResponse.getIsSuccess()) {
                log.info("不良品处理单审核成功:{}", gson.toJson(repoRet.getResult()));
            } else {
                log.error("不良品处理单审核失败:{}",gson.toJson(repoRet.getResult().getResponseStatus()) );
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 组装不良品处理单推送金蝶对象
     * @param badHandle
     * @return
     */
    private BadHandleBo assembleKingBadHandle(KingBadHandleEntity badHandle){
        BadHandleBo badHandleBo = new BadHandleBo();
        //单据类型
        FBillTypeIDBo FBillTypeID = new FBillTypeIDBo().setFNUMBER(badHandle.getDocType());
        badHandleBo.setFBillTypeID(FBillTypeID);
        //备注
        badHandleBo.setFDescription(badHandle.getRemark());
        //业务类型
        badHandleBo.setFBusinessType(badHandle.getDocBusinessType());
        //单据日期
        badHandleBo.setFDate(dateFormat.format(badHandle.getDocTime()));
        //来源组织
        BaseChildBo FSourceOrgId = new BaseChildBo().setFNumber(KingConstUtil.DEFAULT_ORG);
        badHandleBo.setFSourceOrgId(FSourceOrgId);
        //质检组织
        BaseChildBo FInspectOrgId = new BaseChildBo().setFNumber(KingConstUtil.DEFAULT_ORG);
        badHandleBo.setFInspectOrgId(FInspectOrgId);
        //部门
        FBillTypeIDBo FInspectDepId = new FBillTypeIDBo().setFNUMBER(badHandle.getCheckDept());
        badHandleBo.setFInspectDepId(FInspectDepId);
        //质检员
        FBillTypeIDBo FInspectorId = new FBillTypeIDBo().setFNUMBER(badHandle.getCheckBy());
        badHandleBo.setFInspectorId(FInspectorId);
        //质检组
        FBillTypeIDBo FInspectGroupId = new FBillTypeIDBo().setFNUMBER(badHandle.getCheckGroup());
        badHandleBo.setFInspectGroupId(FInspectGroupId);

        /***物料明细***/
        List<BadHandleFEntityBo> FEntity = new ArrayList<>();
        List<KingBadHandleMaterialEntity> materialLists = badHandle.getMaterialLists();
        materialLists.stream().filter(Objects::nonNull).forEach(badHandleMaterial ->{
            BadHandleFEntityBo badHandleFEntityBo = new BadHandleFEntityBo();
            //物料编码
            FBillTypeIDBo FMateridlId = new FBillTypeIDBo().setFNUMBER(badHandleMaterial.getMaterialCode());
            badHandleFEntityBo.setFMateridlId(FMateridlId);
            //供应商
            FBillTypeIDBo FSupplierId = new FBillTypeIDBo().setFNUMBER(badHandleMaterial.getSupplierCode());
            badHandleFEntityBo.setFSupplierId(FSupplierId);
            //客户
            FBillTypeIDBo FCustomerId = new FBillTypeIDBo().setFNUMBER(badHandleMaterial.getCustomerCode());
            badHandleFEntityBo.setFCustomerId(FCustomerId);
            //生产车间
            FBillTypeIDBo FWorkShopId = new FBillTypeIDBo().setFNUMBER(badHandleMaterial.getWorkshop());
            badHandleFEntityBo.setFWorkShopId(FWorkShopId);
            //工序号
            badHandleFEntityBo.setFOperNumber(Integer.parseInt(badHandleMaterial.getProcessNum()));
            //工序说明
            badHandleFEntityBo.setFOperDescription(badHandleMaterial.getProcessDesc());
            //仓库
            BaseChildBo FStockId = new BaseChildBo().setFNumber(badHandleMaterial.getWarehouseCode());
            badHandleFEntityBo.setFStockId(FStockId);
            //批号
            BaseChildBo FLot = new BaseChildBo().setFNumber(badHandleMaterial.getBatchNum());
            badHandleFEntityBo.setFLot(FLot);
            //单位
            BaseChildBo FUnitID = new BaseChildBo().setFNumber(badHandleMaterial.getUnit());
            badHandleFEntityBo.setFUnitID(FUnitID);
            //检验单使用决策
            badHandleFEntityBo.setFUsePolicy(badHandleMaterial.getUseDecision());
            //检验不良数量
            badHandleFEntityBo.setFInspectDefectQty(Integer.parseInt(badHandleMaterial.getCheckBadNum()));
            //序列号
            FBillTypeIDBo FSerialId = new FBillTypeIDBo().setFNUMBER(badHandleMaterial.getSerialNum());
            badHandleFEntityBo.setFSerialId(FSerialId);
            //不良处理
            badHandleFEntityBo.setFDefProcess(badHandleMaterial.getBadHandle());
            //不良数量
            badHandleFEntityBo.setFDefectiveQty(badHandleMaterial.getBadNum());
            //mrb
            badHandleFEntityBo.setFIsMRBReview(badHandleMaterial.getIsMrb());
            //是否折让
            badHandleFEntityBo.setFIsDiscount(badHandleMaterial.getIsDiscount());
            //折让金额
            badHandleFEntityBo.setFDiscountQty(Integer.parseInt(badHandleMaterial.getDiscountAmount()));

            KingBadHandleMaterialDetailEntity materialDetail = badHandleMaterial.getMaterialDetail();
            if(Objects.nonNull(materialDetail)){
                //折让选单金额
                badHandleFEntityBo.setFDisCountSelectQty(Integer.parseInt(materialDetail.getDiscountChooseAmount()));
            }
            FEntity.add(badHandleFEntityBo);
        });
        badHandleBo.setFEntity(FEntity);
        return badHandleBo;
    }







}
